package com.tianji.remark.service.impl;

import com.tianji.common.autoconfigure.mq.RabbitMqHelper;
import com.tianji.common.constants.CacheConstants;
import com.tianji.common.constants.MqConstants;
import com.tianji.common.domain.dto.LikedTimesDTO;
import com.tianji.common.utils.UserContext;
import com.tianji.remark.domain.dto.LikeRecordFormDTO;
import com.tianji.remark.domain.entity.LikedRecord;
import com.tianji.remark.mapper.LikedRecordMapper;
import com.tianji.remark.service.ILikedRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.StringRedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 点赞记录表 服务实现类
 * </p>
 *
 * @author author
 */
@Service
public class LikedRecordServiceImpl extends ServiceImpl<LikedRecordMapper, LikedRecord> implements ILikedRecordService {
    @Autowired
    private RabbitMqHelper mqHelper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public Set<Long> isBizLiked(List<Long> bizIds, String bizType) {
        /*// 1.获取登录用户id
        Long userId = UserContext.getUser();
        // 2.查询点赞状态
        List<LikedRecord> list = lambdaQuery()
                .in(LikedRecord::getBizId, bizIds)
                .eq(LikedRecord::getUserId, userId)
                .list();
        //3.返回结果
        return list.stream().map(LikedRecord::getBizId).collect(Collectors.toSet());*/
        Long userId = UserContext.getUser();
        // pipeline
        List<Object> existList = redisTemplate.executePipelined(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                for (Long bizId : bizIds) {
                    String key = getUserLikedKey(bizId, bizType);
                    StringRedisConnection redisConnection = (StringRedisConnection) connection;
                    // 这条命令的执行结果exist回放到List<Object>来
                    Boolean exist = redisConnection.sIsMember(key, "" + userId);
                }
                return null;
            }
        });
        Set<Long> idSet = new HashSet<>();
        for (int i = 0; i < existList.size(); i++) {
            Object object = existList.get(i);
            Boolean exist = (Boolean) object;
            if (exist != null && exist) {
                idSet.add(bizIds.get(i));
            }
        }
        return idSet;
    }


    @Override
    public void addLikeRecord(LikeRecordFormDTO recordDTO) {
        /*Long userId = UserContext.getUser();
        //判断是否是个点赞
        Boolean liked =recordDTO.getLiked();
        if(liked){
            //说明是点赞
            //查询是否点过赞，userId、bizId、bizType
            LikedRecord likedRecordDB=getLikedRecordMsg(recordDTO, userId);
            //如果没点过
            //新增点赞记录
            if (ObjectUtil.isEmpty(likedRecordDB)){
                LikedRecord likedRecord = BeanUtil.copyProperties(recordDTO, LikedRecord.class);
                LocalDateTime now = LocalDateTime.now();
                likedRecord.setCreateTime(now);
                likedRecord.setUpdateTime(now);
                likedRecord.setUserId(userId);
                this.save(likedRecord);
            }
            //统计点赞数量  //发送MQ
            getLikedRecordCountAndSend(recordDTO);
        }else {
            //说明是取消点赞
            //查询是否点过赞，UserId、bizId、bizType
            LikedRecord likedRecordDB=getLikedRecordMsg(recordDTO, userId);
            //如果没点过赞，return
            if (ObjectUtil.isEmpty(likedRecordDB)){
                return;
            }
            //删除点赞记录
            this.removeById(likedRecordDB.getId());
            //统计点赞数量  //发送MQ
           getLikedRecordCountAndSend(recordDTO);
        }*/
        Long userId = UserContext.getUser();
        Boolean liked = recordDTO.getLiked();
        if (liked) {
            //说明是点赞
            //新增点赞
            String key = getUserLikedKey(recordDTO.getBizId(), recordDTO.getBizType());
            Long add = redisTemplate.opsForSet().add(key, "" + userId);
            if (add != null && add > 0) {
                //添加成功
                //统计点赞数量
                Long size = redisTemplate.opsForSet().size(key);
                redisTemplate.opsForZSet().add(CacheConstants.LIKE_COUNT, recordDTO.getBizType() + ":" + recordDTO.getBizId(), size);
            }
        } else {
            //说明是取消点赞
            //删除记录
            String key = getUserLikedKey(recordDTO.getBizId(), recordDTO.getBizType());
            Long remove = redisTemplate.opsForSet().remove(key, "" + userId);
            if (remove != null && remove > 0) {
                //删除成功
                //统计点赞数量
                Long size = redisTemplate.opsForSet().size(key);
                redisTemplate.opsForZSet().add(CacheConstants.LIKE_COUNT, recordDTO.getBizType() + ":" + recordDTO.getBizId(), size);
            }
        }

    }

    private String getUserLikedKey(Long bizId, String bizType) {
        return CacheConstants.REMARK_PREFIX + bizType + ":" + bizId;
    }

    private void getLikedRecordCountAndSend(LikeRecordFormDTO recordDTO) {
        Integer count = this.lambdaQuery().eq(LikedRecord::getBizId, recordDTO.getBizId())
                .eq(LikedRecord::getBizType, recordDTO.getBizType()).count();
        String key = MqConstants.Key.LIKED_TIMES_KEY_TEMPLATE.replace("{}", recordDTO.getBizType());
        mqHelper.send(MqConstants.Exchange.LIKE_RECORD_EXCHANGE, key, new LikedTimesDTO(recordDTO.getBizId(), count, recordDTO.getBizType()));
    }

    private LikedRecord getLikedRecordMsg(LikeRecordFormDTO recordDTO, Long userId) {
        return this.lambdaQuery().eq(LikedRecord::getUserId, userId)
                .eq(LikedRecord::getBizId, recordDTO.getBizId())
                .eq(LikedRecord::getBizType, recordDTO.getBizType()).one();
    }
}
